package thread.day3;

import java.util.ArrayList;
import java.util.List;

/**
 * 经典的生产/消费者问题
 * 生产者最多生产20个商品,
 * 生产者在有商品时就通知消费者,没有商品就通知消费者停一下
 *
 * @author wx
 * @create 2019-11-28 20:34
 */
public class ProducterConsumerDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        Consumer consumer = new Consumer(list);
        Producter producter = new Producter(list);

        Thread producterThread = new Thread(producter);
        producterThread.setName("生产者1");
        Thread producterThread2 = new Thread(producter);
        producterThread2.setName("生产者2");
        Thread consumerThread2 = new Thread(consumer);
        consumerThread2.setName("消费者B");
        Thread consumerThread = new Thread(consumer);
        consumerThread.setName("消费者A");

        consumerThread.start();
        producterThread.start();
        producterThread2.start();
        consumerThread2.start();
    }
}

class Product {

}

class Consumer implements Runnable {
    List<String> productList;

    public Consumer(List<String> productList) {
        this.productList = productList;
    }

    @Override
    //这里用同步方法为什么会报错?!
    //报错:java.lang.IllegalMonitorStateException
    // a thread has attempted to wait on an object's monitor without owning the specified monitor
    //线程试图在不拥有指定监视器的情况下等待对象的监视器或者唤醒对象的监视器
    //同步方法默认的监视器是this,而这里监视器是productList
    //public  synchronized void run() {
    public void run() {
        while (true) {
            synchronized (productList) {
                try {
                    Thread.sleep(200);
                    productList.notify();
                    if (productList.size() > 0) {
                        productList.remove(productList.size() - 1);
                        System.out.println(Thread.currentThread().getName() + " 消费了: 商品" + productList.size());
                        productList.wait();
                    } else {
                        System.out.println(Thread.currentThread().getName() + " 没有消费到商品");
                        productList.wait();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

class Producter implements Runnable {
    List<String> productList;


    public Producter(List<String> productList) {
        this.productList = productList;
    }

    @Override

    public void run() {
        while (true) {
            synchronized (productList) {
                try {
                    Thread.sleep(100);

                    //小于20,没生产满,生产一个
                    if (productList.size() < 20) {
                        productList.notify();
                        productList.add("A");
                        System.out.println(Thread.currentThread().getName() + "生产了: 商品" + +productList.size());
                        productList.wait();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
